#include "GY_FormatFloat.h"
#include <QtDebug>

GY_FormatFloat::GY_FormatFloat(const QString &guid, QGraphicsItem *parent)
    :GY_BasicsCalculators(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("FormatFloat"));
    initializationPropertyInfo();
}

void GY_FormatFloat::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateObjectName;
    m_PropertyInfoMap.insert(ObjectName.propertyName,ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    GY_PropertyInfo Value(this);
    Value.propertyName = "Value";
    Value.propertyValue = 0;
    Value.updateType = Update;
    Value.propertyType = DoublePropertyType;
    Value.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateValue;
    m_PropertyInfoMap.insert(Value.propertyName,Value);
    m_PropertyInfoMap[Value.propertyName].setConnect();

    GY_PropertyInfo MinLength(this);
    MinLength.propertyName = "MinLength";
    MinLength.propertyValue = 3;
    MinLength.updateType = Update;
    MinLength.propertyType = IntPropertyType;
    MinLength.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateMinLength;
    m_PropertyInfoMap.insert(MinLength.propertyName,MinLength);
    m_PropertyInfoMap[MinLength.propertyName].setConnect();

    GY_PropertyInfo MaxLength(this);
    MaxLength.propertyName = "MaxLength";
    MaxLength.propertyValue = 9;
    MaxLength.updateType = Update;
    MaxLength.propertyType = IntPropertyType;
    MaxLength.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateMaxLength;
    m_PropertyInfoMap.insert(MaxLength.propertyName,MaxLength);
    m_PropertyInfoMap[MaxLength.propertyName].setConnect();

    GY_PropertyInfo NumDecimalPlaces(this);
    NumDecimalPlaces.propertyName = "NumDecimalPlaces";
    NumDecimalPlaces.propertyValue = 2;
    NumDecimalPlaces.updateType = Update;
    NumDecimalPlaces.propertyType = IntPropertyType;
    NumDecimalPlaces.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateNumDecimalPlaces;
    m_PropertyInfoMap.insert(NumDecimalPlaces.propertyName,NumDecimalPlaces);
    m_PropertyInfoMap[NumDecimalPlaces.propertyName].setConnect();

    GY_PropertyInfo PlusSignMethod(this);
    PlusSignMethod.propertyName = "PlusSignMethod";
    PlusSignMethod.propertyValue = "NoPlusSign";//PlusSign+加号,Blank空格
    PlusSignMethod.updateType = Update;
    PlusSignMethod.propertyType = QStringPropertyType;
    PlusSignMethod.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updatePlusSignMethod;
    m_PropertyInfoMap.insert(PlusSignMethod.propertyName,PlusSignMethod);
    m_PropertyInfoMap[PlusSignMethod.propertyName].setConnect();

    GY_PropertyInfo LeadingZeros(this);
    LeadingZeros.propertyName = "LeadingZeros";
    LeadingZeros.propertyValue = false;
    LeadingZeros.updateType = Update;
    LeadingZeros.propertyType = BoolPropertyType;
    LeadingZeros.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateLeadingZeros;
    m_PropertyInfoMap.insert(LeadingZeros.propertyName,LeadingZeros);
    m_PropertyInfoMap[LeadingZeros.propertyName].setConnect();

    GY_PropertyInfo OverflowChar(this);
    OverflowChar.propertyName = "OverflowChar";
    OverflowChar.propertyValue = "*";
    OverflowChar.updateType = Update;
    OverflowChar.propertyType = QStringPropertyType;
    OverflowChar.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateOverflowChar;
    m_PropertyInfoMap.insert(OverflowChar.propertyName,OverflowChar);
    m_PropertyInfoMap[OverflowChar.propertyName].setConnect();

    GY_PropertyInfo OutputCapacity(this);
    OutputCapacity.propertyName = "Output.Capacity";
    OutputCapacity.propertyValue = 9;
    OutputCapacity.updateType = Update;
    OutputCapacity.propertyType = IntPropertyType;
    OutputCapacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateOutputCapacity;
    m_PropertyInfoMap.insert(OutputCapacity.propertyName,OutputCapacity);
    m_PropertyInfoMap[OutputCapacity.propertyName].setConnect();

    GY_PropertyInfo Output(this);
    Output.propertyName = "Output";
    Output.propertyValue = "0.00";
    Output.updateType = Update;
    Output.propertyType = QStringPropertyType;
    Output.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_FormatFloat::updateOutput;
    m_PropertyInfoMap.insert(Output.propertyName,Output);
    m_PropertyInfoMap[Output.propertyName].setConnect();
}

bool GY_FormatFloat::updateValue(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>()) {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateMinLength(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>()) {
        return false;
    }
    //最小长度>最大长度时，最小长度被约束等于最大长度
    if(value.toInt()>m_PropertyInfoMap["MaxLength"].propertyValue.toInt()) {
        m_PropertyInfoMap[name].propertyValue = m_PropertyInfoMap["MaxLength"].propertyValue.toInt();
    }else {
        m_PropertyInfoMap[name].propertyValue = value;
    }
    setOutput();
    return true;
}

bool GY_FormatFloat::updateMaxLength(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>()) {
        return false;
    }
    int max = value.toInt();
    if(max>9) {
        max = 9;
    }
    //最大长度>长度限制值Output.Capacity，限制值应该扩大为最大长度
    if(max>m_PropertyInfoMap["Output.Capacity"].propertyValue.toInt()) {
        m_PropertyInfoMap["Output.Capacity"].propertyValue = max;
    }
    //最大长度<最小长度时，最小长度被约束等于最大长度
    if(max<m_PropertyInfoMap["MinLength"].propertyValue.toInt()) {
        m_PropertyInfoMap["MinLength"].propertyValue = max;
    }
    m_PropertyInfoMap[name].propertyValue = max;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateNumDecimalPlaces(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>()) {
        return false;
    }
    if(value.toInt()>6) {
        m_PropertyInfoMap[name].propertyValue = 6;
    }else {
        m_PropertyInfoMap[name].propertyValue = value;
    }
    setOutput();
    return true;
}

bool GY_FormatFloat::updatePlusSignMethod(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QString>()) {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateLeadingZeros(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>()) {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateOverflowChar(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QString>()) {
        return false;
    }
    QByteArray tmp = value.toByteArray();
    //判断字符是否正确(字节长度为1)
    if(tmp.size() != 1) {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateOutputCapacity(const QString &name, const QVariant &value)
{
    if(!value.canConvert<int>()) {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    setOutput();
    return true;
}

bool GY_FormatFloat::updateOutput(const QString &, const QVariant &)
{
   return false;
}

void GY_FormatFloat::setOutput()
{
    //各个属性的值
    double Value = m_PropertyInfoMap["Value"].propertyValue.toDouble();
    //正负判断
    bool character = true;
    if(Value<0) {
        character = false;
    }
    //Value转字符串
    QString str = QString("%1").arg(Value);
    //最小长度、最大长度、小数点数目、前置符号、是否补零
    int MinLength = m_PropertyInfoMap["MinLength"].propertyValue.toInt();
    int MaxLength = m_PropertyInfoMap["MaxLength"].propertyValue.toInt();
    int NumDecimalPlaces = m_PropertyInfoMap["NumDecimalPlaces"].propertyValue.toInt();
    QString PlusSignMethod = m_PropertyInfoMap["PlusSignMethod"].propertyValue.toString();
    bool LeadingZeros = m_PropertyInfoMap["LeadingZeros"].propertyValue.toBool();

    //位数不够时补0还是空判断
    QChar fill(' ');
    if(LeadingZeros) {
        fill = '0';
    }
    //溢出替换符号
    QString OverflowCharStr = m_PropertyInfoMap["OverflowChar"].propertyValue.toString();
    QChar OverflowChar = OverflowCharStr.at(0);
    int OutputCapacity = m_PropertyInfoMap["Output.Capacity"].propertyValue.toInt();

    //把字符串str以'.'进行分割
    QStringList list = str.split('.');
    //整数部分
    QString integer = list.at(0);
    if(character) {
        if(PlusSignMethod == "Blank") {
            integer.insert(0,' ');
        }else if(PlusSignMethod == "PlusSign") {
            integer.insert(0,'+');
        }
    }
    //小数部分
    QString decimalNumber;
    if(list.size() == 1) {
        //只有整数部分，小数全补0
        for(int i=0;i<NumDecimalPlaces;i++) {
            decimalNumber.append('0');
        }
    }else {
        decimalNumber = list.at(1);
        int size = decimalNumber.size();
        //小数部分大于限制个数切掉多余部分
        if(size>=NumDecimalPlaces) {
            decimalNumber = decimalNumber.left(NumDecimalPlaces);
        }else {
            for(int i=0;i<NumDecimalPlaces-size;i++) {
                decimalNumber.append('0');
            }
        }
    }

    //准备输出的字符串
    QString output = integer + '.' + decimalNumber;
    if(output.size()>MaxLength) {
        //长度超过最大长度
        QString error;
        for(int i=0;i<MaxLength;i++) {
            error.append(OverflowChar);
        }
        error = error.left(OutputCapacity);
        m_PropertyInfoMap["Output"].propertyValue = error;
        return;
    }else if((output.size()==9)&&(PlusSignMethod == "NoPlusSign")&&character) {
        //长度为9且无符号
        QString error;
        for(int i=0;i<MaxLength;i++) {
            error.append(OverflowChar);
        }
        error = error.left(OutputCapacity);
        m_PropertyInfoMap["Output"].propertyValue = error;
        return;
    }else if(output.size()<MinLength) {
        //比最小长度还小，补0或者空格
        int count = MinLength-output.size();
        if((output.at(0)==' ')||(output.at(0)=='+')||(output.at(0)=='-')) {
            for(int i=0;i<count;i++) {
                output.insert(1, fill);
            }
        }else {
            for(int i=0;i<count;i++) {
                output.insert(0, fill);
            }
        }
    }

    output = output.left(OutputCapacity);
    m_PropertyInfoMap["Output"].propertyValue = output;
}





